package com.hifar.test.report.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hifar.abi.utils.minio.MinioUtils;
import com.hifar.fw.utils.lang.StringUtils;
import com.hifar.idm.util.ConvertPdfUtil;
import com.hifar.log.AutoLogUtils;
import com.hifar.plat.baseModal.pojo.BaseOssFiles;
import com.hifar.plat.baseModal.service.IBaseOssFilesService;
import com.hifar.sys.MinioUtil;
import com.hifar.sys.SystemLoginUser;
import com.hifar.test.api.model.ReportApiResultVO;
import com.hifar.test.entrust.constant.ReportConsts;
import com.hifar.test.entrust.pojo.HfEnvEntrust;
import com.hifar.test.entrust.pojo.HfEnvGkEntrust;
import com.hifar.test.entrust.service.IHfEnvEntrustService;
import com.hifar.test.entrust.service.IHfEnvGkEntrustService;
import com.hifar.test.report.mapper.HfEnvReportMapper;
import com.hifar.test.report.pojo.HfEnvReport;
import com.hifar.test.report.pojo.HfEnvTestReport;
import com.hifar.test.report.pojo.VO.HfEnvReportVO;
import com.hifar.test.report.pojo.VO.ReportApproveVO;
import com.hifar.test.report.pojo.VO.ReportCreateVO;
import com.hifar.test.report.pojo.VO.ReportPushVO;
import com.hifar.test.report.pojo.model.ReportPushModel;
import com.hifar.test.report.render.HfEnvReportRender;
import com.hifar.test.report.render.HfEnvReportSignRender;
import com.hifar.test.report.service.IHfEnvReportRecordService;
import com.hifar.test.report.service.IHfEnvReportService;
import com.hifar.test.report.service.IHfEnvTestReportService;
import com.hifar.test.test.pojo.HfEnvTest;
import com.hifar.test.test.service.IHfEnvTestService;
import com.hifar.utils.FileUtil;
import com.tssk.kylx.fw.utils.id.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.io.File;
import java.util.*;

/**
 * @author zhuWeiWei
 * @description 环境报告
 * @date 2024/12/26 13:45
 */
@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class HfEnvReportServiceImpl extends ServiceImpl<HfEnvReportMapper, HfEnvReport> implements IHfEnvReportService {

    @Autowired
    private IHfEnvReportRecordService reportRecordService;
    @Autowired
    private IBaseOssFilesService baseOssFilesService;
    @Autowired
    private HfEnvReportRender reportRender;

    @Autowired
    private IHfEnvEntrustService iHfEnvEntrustService;

    @Autowired
    private IHfEnvGkEntrustService gkEntrustService;
    @Autowired
    private HfEnvReportSignRender envReportSignRender;

    @Autowired
    private IHfEnvTestService hfEnvTestService;

    @Autowired
    private AutoLogUtils autoLogUtils;

    @Autowired
    private IHfEnvTestReportService testReportService;

    @Override
    public void submitReport(String id) {
        HfEnvReport envReport = getById(id);
        Assert.notNull(envReport, "报告数据不存在!");
        String reportStatus = envReport.getStatus();
        Assert.isTrue(!Arrays.asList(ReportConsts.REPORT_STATUS_DPZ, ReportConsts.REPORT_STATUS_TJ, ReportConsts.REPORT_STATUS_PZTG).contains(reportStatus)
                , "报告已提交,请刷新后再试!");
        envReport.setStatus(ReportConsts.REPORT_STATUS_TJ);
        this.updateById(envReport);
        reportRecordService.saveSubmitRecord(id);

        String reportCode = envReport.getReportCode();

        autoLogUtils.addLog("环境试验-试验报告", String.format("报告提交审批:【%s】", reportCode));

    }

    @Override
    public void examinePass(ReportApproveVO reportApproveVO) {
        String id = reportApproveVO.getId();
        String remarks = reportApproveVO.getRemarks();
        HfEnvReport envReport = getById(id);
        Assert.notNull(envReport, "报告数据不存在!");
        String status = envReport.getStatus();
        Assert.isTrue(Objects.equals(ReportConsts.REPORT_STATUS_TJ, status), "报告已审批,请刷新后再试!");
        envReport.setStatus(ReportConsts.REPORT_STATUS_DPZ);
        envReport.setExamineUserId(SystemLoginUser.userId);
        reportRecordService.saveRecord(id, ReportConsts.REPORT_OPT_TYPE_EXAMINE_PASS, remarks);
        this.updateById(envReport);
        String reportCode = envReport.getReportCode();
        autoLogUtils.addLog("环境试验-报告审核", String.format("报告审核通过:【%s】", reportCode));
    }

    @Override
    public void examineReject(ReportApproveVO reportApproveVO) {
        String id = reportApproveVO.getId();
        String remarks = reportApproveVO.getRemarks();
        HfEnvReport envReport = getById(id);
        Assert.notNull(envReport, "报告数据不存在!");
        String status = envReport.getStatus();
        Assert.isTrue(Objects.equals(ReportConsts.REPORT_STATUS_TJ, status), "报告已审批,请刷新后再试!");
        envReport.setStatus(ReportConsts.REPORT_STATUS_SHBH);
        this.updateById(envReport);
        reportRecordService.saveRecord(id, ReportConsts.REPORT_OPT_TYPE_EXAMINE_REJECT, remarks);

        String reportCode = envReport.getReportCode();
        autoLogUtils.addLog("环境试验-报告审核", String.format("报告审核驳回:【%s】", reportCode));
    }

    @Override
    public void approvePass(ReportApproveVO reportApproveVO) {
        String id = reportApproveVO.getId();
        String remarks = reportApproveVO.getRemarks();
        HfEnvReport envReport = getById(id);
        Assert.notNull(envReport, "报告数据不存在!");
        String status = envReport.getStatus();
        String entrustId = envReport.getEntrustId();
        String gkEntrustId = envReport.getGkEntrustId();
        // 验证委托单存在性
//        HfEnvEntrust hfEnvEntrust = iHfEnvEntrustService.getById(entrustId);
        HfEnvGkEntrust gkEntrust = gkEntrustService.getById(gkEntrustId);

        Assert.notNull(gkEntrust, "委托单不存在!");
        Assert.isTrue(Objects.equals(ReportConsts.REPORT_STATUS_DPZ, status), "报告已审批,请刷新后再试!");
        envReport.setStatus(ReportConsts.REPORT_STATUS_PZTG);
        envReport.setApproveUserId(SystemLoginUser.userId);
        reportRecordService.saveRecord(id, ReportConsts.REPORT_OPT_TYPE_APPROVE_PASS, remarks);
        // 渲染批准人签名
        try {
            envReportSignRender.renderReport(envReport);
        } catch (Exception e) {
            // 记录详细错误信息
            String errorMsg = String.format("报告签名渲染失败，报告ID: %s, 错误: %s", id, e.getMessage());
            autoLogUtils.addLog("环境试验-报告批准", errorMsg);
            // 抛出业务异常，确保事务回滚
            throw new RuntimeException("报告签名渲染失败，请检查签名文件是否存在: " + e.getMessage(), e);
        }

        this.updateById(envReport);

        String reportCode = envReport.getReportCode();
        autoLogUtils.addLog("环境试验-报告批准", String.format("报告批准通过:【%s】", reportCode));
    }

    @Override
    public void approveReject(ReportApproveVO reportApproveVO) {
        String id = reportApproveVO.getId();
        String remarks = reportApproveVO.getRemarks();
        HfEnvReport envReport = getById(id);
        Assert.notNull(envReport, "报告数据不存在!");
        String status = envReport.getStatus();
        Assert.isTrue(Objects.equals(ReportConsts.REPORT_STATUS_DPZ, status), "报告已审批,请刷新后再试!");
        envReport.setStatus(ReportConsts.REPORT_STATUS_PZBH);
        this.updateById(envReport);
        reportRecordService.saveRecord(id, ReportConsts.REPORT_OPT_TYPE_APPROVE_REJECT, remarks);

        String reportCode = envReport.getReportCode();
        autoLogUtils.addLog("环境试验-报告批准", String.format("报告批准驳回:【%s】", reportCode));
    }

    @Override
    public void generateReport(ReportCreateVO reportCreateVO) {
        List<String> testIdList = reportCreateVO.getTestIdList();
        String templateId = reportCreateVO.getTemplateId();
        HfEnvReport hfEnvReport = reportRender.renderReport(reportCreateVO);
        String reportId = hfEnvReport.getId();

        List<HfEnvTestReport> testReportList = new ArrayList<>(testIdList.size());
        for (String testId : testIdList) {
            HfEnvTestReport hfEnvTestReport = new HfEnvTestReport();
            hfEnvTestReport.setStatus("1");
            hfEnvTestReport.setReportId(reportId);
            hfEnvTestReport.setTestId(testId);
            testReportList.add(hfEnvTestReport);
        }

        // 将试验状态改成已出报告 （izIssueReport 是否已出报告 1 是 2 否）
        UpdateWrapper<HfEnvTest> testUpdateWrapper = new UpdateWrapper<>();
        testUpdateWrapper.lambda()
                .set(HfEnvTest::getIzIssueReport, "1")
                .in(HfEnvTest::getId, testIdList);
        hfEnvTestService.update(testUpdateWrapper);

        // 保存试验-报告关联关系到数据库
        testReportService.saveBatch(testReportList);
        reportRecordService.saveCreateRecord(reportId);

        String reportCode = hfEnvReport.getReportCode();
        autoLogUtils.addLog("环境试验-试验报告", String.format("报告生成:【%s】", reportCode));
    }

    @Override
    public Page<HfEnvReportVO> pageVO(Page page, QueryWrapper<HfEnvReportVO> queryWrapper) {
        return baseMapper.pageVO(page, queryWrapper);
    }

    @Override
    public List<HfEnvReport> listByEntrustId(String entrustId) {
        QueryWrapper<HfEnvReport> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(HfEnvReport::getEntrustId, entrustId)
                .orderByDesc(HfEnvReport::getCreateTime);
        List<HfEnvReport> reportList = this.list(queryWrapper);
        for (HfEnvReport hfEnvReport : reportList) {
            String wordPath = hfEnvReport.getWordPath();
            String pdfPath = hfEnvReport.getPdfPath();
            Integer secretLevel = hfEnvReport.getSecretLevel();
            if (StringUtils.isNotBlank(wordPath)) {
                String wordFullPath = MinioUtil.getFullFilePaths(MinioUtil.PRE_DEFAULT, wordPath, secretLevel);
                hfEnvReport.setWordPath(wordFullPath);
            }
            if (StringUtils.isNotBlank(pdfPath)) {
                String pdfFullPath = MinioUtil.getFullFilePaths(MinioUtil.PRE_DEFAULT, pdfPath, secretLevel);
                hfEnvReport.setPdfPath(pdfFullPath);
            }
        }
        return reportList;
    }

    @Override
    public HfEnvReport replaceReport(String id, String fileId) {
        HfEnvReport envReport = this.getById(id);
        String reportCode = envReport.getReportCode();
        Assert.notNull(envReport, "数据不存在!");
        BaseOssFiles baseOssFiles = baseOssFilesService.getById(fileId);
        Assert.notNull(baseOssFiles, "附件不存在!");
        String filePath = baseOssFiles.getFilePath();
        String bucketPre = baseOssFiles.getBucketPre();

        String tempPath = FileUtil.getTempPath();
        String tempId = IdUtils.uuid32();
        String wordTempPath = tempPath + File.separator + tempId + ".docx";
        String wordObjectName = "hifar/idm/" + tempId + ".docx";
        String pdfObjectName = "hifar/idm/" + tempId + ".pdf";

        try {
            MinioUtil.downloadFileToLocal(bucketPre, filePath, wordTempPath);
            String tempPdfPath = ConvertPdfUtil.wordToPdf(wordTempPath);
            MinioUtils.uploadLocalFileToMinio(MinioUtil.PRE_DEFAULT, wordObjectName, wordTempPath);
            MinioUtils.uploadLocalFileToMinio(MinioUtil.PRE_DEFAULT, pdfObjectName, tempPdfPath, "application/pdf");
            envReport.setPdfPath(pdfObjectName);
            envReport.setWordPath(wordObjectName);
            this.updateById(envReport);
        } catch (Exception e) {
            e.printStackTrace();
        }
        autoLogUtils.addLog("环境试验-试验报告", String.format("报告替换:【%s】", reportCode));
        return envReport;
    }


    @Override
    public void updateEntrustId(String gkEntrustId, String entrustId) {
        this.lambdaUpdate()
                .set(HfEnvReport::getEntrustId, entrustId)
                .eq(HfEnvReport::getGkEntrustId, gkEntrustId)
                .update();
    }

    @Override
    public void pushReport(ReportPushVO reportPushVO) {
        String id = reportPushVO.getReportId();
        HfEnvReport hfEnvReport = getById(id);
        Assert.notNull(hfEnvReport, "报告数据不存在!");
        String gkEntrustId = hfEnvReport.getGkEntrustId();
        HfEnvGkEntrust gkEntrust = gkEntrustService.getById(gkEntrustId);
        Assert.notNull(gkEntrust, "委托数据不存在!");
        ReportPushModel reportPushModel = new ReportPushModel();
        reportPushModel.setReportCode(hfEnvReport.getReportCode());
        reportPushModel.setEntrustCust(gkEntrust.getEntrustCust());
        reportPushModel.setEntrustUserName(gkEntrust.getEntrustUserName());
        reportPushModel.setReportCreateTime(hfEnvReport.getCreateTime());
        List<HfEnvTest> testList = hfEnvTestService.listByGkEntrustId(gkEntrustId);
        Date testStartTime = null;
        Date testEndTime = null;
        Set<String> unitNameSet = new HashSet<>();
        for (HfEnvTest hfEnvTest : testList) {
            Date realStartTime = hfEnvTest.getRealStartTime();
            Date realEndTime = hfEnvTest.getRealEndTime();
            String unitName = hfEnvTest.getUnitName();
            if (testStartTime == null) {
                testStartTime = realStartTime;
            } else {
                testStartTime = testStartTime.before(realStartTime) ? testStartTime : realStartTime;
            }

            if (testEndTime == null) {
                testEndTime = realEndTime;
            } else {
                testEndTime = testEndTime.before(realEndTime) ? testEndTime : realEndTime;
            }
            unitNameSet.add(unitName);
        }
        reportPushModel.setTestStartTime(testStartTime);
        reportPushModel.setTestEndTime(testEndTime);
        reportPushModel.setEntrustCode(gkEntrust.getEntrustCode());
        reportPushModel.setUnitNames(String.join(",", unitNameSet));
        Integer secretLevel = hfEnvReport.getSecretLevel();
        String wordPath = hfEnvReport.getWordPath();
        String pdfPath = hfEnvReport.getPdfPath();
        if (StringUtils.isNotBlank(wordPath)) {
            String wordFullPath = MinioUtil.getFullFilePaths(MinioUtil.PRE_DEFAULT, wordPath, secretLevel);
            reportPushModel.setWordPath(wordFullPath);
        }
        if (StringUtils.isNotBlank(pdfPath)) {
            String pdfFullPath = MinioUtil.getFullFilePaths(MinioUtil.PRE_DEFAULT, pdfPath, secretLevel);
            reportPushModel.setPdfPath(pdfFullPath);
        }
        System.out.println("reportPushModel = " + reportPushModel);
        // TODO:待推送逻辑
    }

    @Override
    public Page<ReportApiResultVO> pageApiVO(Page page, QueryWrapper<ReportApiResultVO> queryWrapper) {
        return baseMapper.pageApiVO(page, queryWrapper);
    }
}
